package edu.kit.aifb.ldstream.learner.query;

import org.openrdf.model.URI;
import org.openrdf.query.BooleanQuery;
import org.openrdf.query.MalformedQueryException;
import org.openrdf.query.QueryEvaluationException;
import org.openrdf.query.QueryLanguage;
import org.openrdf.query.TupleQuery;
import org.openrdf.query.TupleQueryResult;
import org.openrdf.repository.RepositoryConnection;
import org.openrdf.repository.RepositoryException;

import edu.kit.aifb.ldstream.env.Environment;

public class OccurrenceQuery {

	private RepositoryConnection con;
	
	public OccurrenceQuery() {
		try {
			this.con = Environment.REPO.getConnection();
		} catch (RepositoryException e) {
			e.printStackTrace();
		}
	}
	
	public int countOccurrence(URI instance, URI pred){
		if(instance == null){
			throw new IllegalArgumentException("OccurrenceQuery.countOccurrence(): instance must not be null.");
		}
		if(pred == null){
			throw new IllegalArgumentException("OccurrenceQuery.countOccurrence(): predicate must not be null.");
		}
		int occurence = 0;
		boolean directLink = false;
		
		String query = "ASK { <" + instance.stringValue() + "> <" + pred.stringValue() + "> ?x }";
		try {
			BooleanQuery booleanQuery = this.con.prepareBooleanQuery(QueryLanguage.SPARQL, query);
			directLink = booleanQuery.evaluate();
		} catch (RepositoryException e) {
			e.printStackTrace();
		} catch (MalformedQueryException e) {
			e.printStackTrace();
		} catch (QueryEvaluationException e) {
			e.printStackTrace();
		}
		
		if(directLink){
			/*
			query = "SELECT (COUNT(?x) AS ?count) FROM <" 
					+ Environment.STREAM_CONTEXT_URI.stringValue() 
					+"> WHERE { <" + instance.stringValue() +"> <" + pred.stringValue() + "> ?x }" ;
			*/
			query = "SELECT (COUNT(?x) AS ?count)  WHERE { <" + instance.stringValue() +"> <" + pred.stringValue() + "> ?x }" ;
		} else{
			/*
		
			query = "SELECT (COUNT(?predicate) AS ?count) FROM <"
					+ Environment.STREAM_CONTEXT_URI.stringValue() 
					+ "> WHERE { <" + instance.stringValue() +"> ?predicate ?x FILTER(isBLANK(?x)) } ";
			 */
			query = "SELECT (COUNT(?predicate) AS ?count) WHERE { <" + instance.stringValue() +"> ?predicate ?x FILTER(isBLANK(?x)) } ";
		}
		
		try {
			TupleQuery tupleQuery = this.con.prepareTupleQuery(QueryLanguage.SPARQL, query);
			try {
				TupleQueryResult result = tupleQuery.evaluate();
				occurence = Integer.parseInt(result.next().getValue("count").stringValue());
				result.close();
			} catch (QueryEvaluationException e) {
				e.printStackTrace();
			}
		} catch (RepositoryException e) {
			e.printStackTrace();
		} catch (MalformedQueryException e) {
			e.printStackTrace();
		}
		
		return occurence;
	}
	
	public void close(){
		try {
			this.con.close();
		} catch (RepositoryException e) {
			e.printStackTrace();
		}
	}
}
